package org.pinda.gui;

import static org.johnnei.engine.render.RenderObject.VERTEX_COLOR;

import org.johnnei.engine.GameKeyboard;
import org.johnnei.engine.render.ColorHelper;
import org.johnnei.engine.render.TextRenderer;
import org.johnnei.engine.render.VertexHelper;
import org.lwjgl.input.Keyboard;

public class GuiTextBox extends GuiComponent {

	private static final int BLINK_RATE = 500;
	
	private ColorHelper backgroundColor;
	private ColorHelper textColor;
	/**
	 * The entered text
	 */
	private String input;
	/**
	 * The position of the cursor
	 */
	private int cursorOffset;
	/**
	 * If this textBox is allowed to take keyboard input
	 */
	private boolean hasFocus;
	/**
	 * A counter to process the blinking bar at the cursor position
	 */
	private int blinkAge;
	/**
	 * A bool to show if the blink bar should be drawn
	 */
	private boolean showBlinkBar;
	
	public GuiTextBox(Gui parent, String defaultText, float x, float y, float width, float height, ColorHelper backgroundColor, ColorHelper textColor) {
		super(parent, VERTEX_COLOR);
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
		this.backgroundColor = backgroundColor;
		this.textColor = textColor;
		this.input = defaultText;
		this.cursorOffset = defaultText.length();
		this.hasFocus = false;
		generateVertexData();
		generateColorData();
	}
	
	@Override
	public void generateVertexData() {
		renderObject.updateVertex(new VertexHelper(x, y, width, height));
	}
	
	@Override
	public void generateColorData() {
		renderObject.updateColor(backgroundColor);
	}
	
	@Override
	public void onClick(int mouseButton, int x, int y) {
		hasFocus = true;
	}
	
	@Override
	public void onKeyPress(char c) {
		if(!hasFocus)
			return;

		if(c < 32) {
			//Non alphanumeric character
			if(c == 8) { //Backspace
				if(input.length() > 0) {
					if(cursorOffset > 1) {
						char[] chars = input.toCharArray();
						System.arraycopy(chars, cursorOffset - 1, chars, cursorOffset - 2, chars.length - cursorOffset);
						input = new String(chars, 0, input.length() - 1);
						cursorOffset--;
					} else if (cursorOffset == 1) {
						input = input.substring(1);
						cursorOffset--;
					}
				}
			}
		} else if (c < 127){ //Typable characters
			char[] chars = input.toCharArray();
			char[] newChars = new char[input.length() + 1];
			if(chars.length == 0) {
				newChars[0] = c;
				input = new String(newChars);
				cursorOffset++;
			} else {
				System.arraycopy(chars, 0, newChars, 0, cursorOffset);
				newChars[cursorOffset] = c;
				System.arraycopy(chars, cursorOffset, newChars, cursorOffset + 1, chars.length - cursorOffset);
				input = new String(newChars);
				cursorOffset++;
			}
		}
	}
	
	@Override
	public void removeFocus() {
		hasFocus = false;
	}
	
	@Override
	public boolean hasFocus() {
		return hasFocus;
	}
	
	@Override
	public void onTick(int deltaMs) {
		blinkAge += deltaMs;
		showBlinkBar = (blinkAge / BLINK_RATE) % 2 == 0;
		
		if(hasFocus) {
			if(GameKeyboard.getInstance().isKeyPressed(Keyboard.KEY_LEFT) && cursorOffset > 0) {
				--cursorOffset;
			}
			if(GameKeyboard.getInstance().isKeyPressed(Keyboard.KEY_RIGHT) && cursorOffset < input.length()) {
				++cursorOffset;
			}
		}
	}
	
	@Override
	public void render() {
		super.render();
		TextRenderer.draw(x + GuiButton.PADDING, y + GuiButton.PADDING, input, (textColor != null) ? textColor : null);
		if(hasFocus && showBlinkBar) {
			TextRenderer.draw(x + GuiButton.PADDING + TextRenderer.getTextWidth(input.substring(0, cursorOffset)), y + GuiButton.PADDING, "|", (textColor != null) ? textColor : null);
		}
	}
	
	public String getText() {
		return input;
	}

}
